package com.LachesismStorm.lachesism.member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.LachesismStorm.lachesism.core.common.response.ResponsePage;
import com.LachesismStorm.lachesism.core.common.response.ResponseResult;
import com.LachesismStorm.lachesism.core.exception.Asserts;
import com.LachesismStorm.lachesism.core.service.RedisService;
import com.LachesismStorm.lachesism.core.util.AsyncUtil;
import com.LachesismStorm.lachesism.core.util.CommonUtil;
import com.LachesismStorm.lachesism.core.util.LachesismTools;
import com.LachesismStorm.lachesism.member.mapper.LuntaiMapper;
import com.LachesismStorm.lachesism.member.mapper.UmsUserMapper;
import com.LachesismStorm.lachesism.member.service.LuntaiService;
import com.LachesismStorm.lachesism.member.util.MemberUtil;
import com.LachesismStorm.lachesism.member.vo.*;
import com.LachesismStorm.lachesism.member.vo.dto.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import static com.LachesismStorm.lachesism.core.util.QRCodeGenerator.generateQRCodeBase64;


/**
 * @Author lachesism
 * @Date 2024-04-10 16:07
 **/
@Service
public class LuntaiServiceImpl implements LuntaiService {

    private static final int MAX_RETRIES = 3;  // 最大重试次数
    private static final int RETRY_INTERVAL = 1000;  // 重试间隔（1秒）
    @Resource
    private LuntaiMapper luntaiMapper;

    @Resource
    private UmsUserMapper memberMapper;
    @Resource
    private RedisService redisService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Value("${file.tyre.address}")
    private String tyreAddress;

    @Value("${file.video.address}")
    private String videoAddress;

    @Value("${url.pc}")
    private String webUrl;

    @Value("${wechat.appID}")
    private String appID;

    @Value("${wechat.appSecret}")
    private String appSecret;

    @Override
    public Integer addCarInfo(LuntaiUserCar car) {
        car.setUserId(MemberUtil.getUserId());
        if (car.getLicensePlate() != null) {
            Integer count = luntaiMapper.selectExistCar(car.getLicensePlate());
            if (count > 0) {
                Asserts.fail("车牌号" + car.getLicensePlate() + " 已存在");
            }
        }
        luntaiMapper.addCarInfo(car);
        return car.getId();
    }

    @Override
    public List<UserCarsDto> getCars() {
        return luntaiMapper.getCarsByUserId(MemberUtil.getUserId());
    }

    @Override
    public void updateCar(LuntaiUserCar car) {
        luntaiMapper.updateCar(car);
    }

    @Override
    public void updateTyreInfo(LuntaiUserTyre tyre) {
        luntaiMapper.updateTyreInfo(tyre);
    }

    @Override
    public List<LuntaiUserTyre> getTyreInfoByCarId(Integer carId) {
        return luntaiMapper.getTyreInfoByCarId2(carId);
    }

    @Override
    public List<LuntaiTyre> getTyreBrand() {
        return luntaiMapper.getTyreBrand();
    }

    @Override
    public void policyExtensionRequest(LuntaiPolicyExtensionRequest request) {
        request.setUserId(MemberUtil.getUserId());
        Integer carId = request.getCarId();
        LuntaiUserCar carById = luntaiMapper.getCarById(carId);
        Integer isCommercial = carById.getIsCommercial();
        request.setIsCommercial(isCommercial);
        luntaiMapper.policyExtensionRequest(request);
        List<LuntaiRequestTyre> tyreList = request.getTyreList();
        for (LuntaiRequestTyre luntaiRequestTyre : tyreList) {
            luntaiRequestTyre.setRequestId(request.getId());
        }
        luntaiMapper.batchAddRequestTyre(tyreList);
        createOrder(request.getType(), request.getId(), request.getStoreId(), MemberUtil.getUserId());
    }

    @Override
    public void editPolicyExtensionRequest(LuntaiPolicyExtensionRequest request) {
        luntaiMapper.editPolicyExtensionRequest(request);
    }

    @Override
    public List<PolicyExtensionRequestDto> getPolicyExtensionRequestList(Integer status) {
        return luntaiMapper.getPolicyExtensionRequestList(MemberUtil.getUserId(), status);
    }

    @Override
    public PolicyExtensionRequestInfoDto getPolicyExtensionRequestInfo(Integer requestId) {
        LuntaiPolicyExtensionRequest request = luntaiMapper.getPolicyExtensionRequestInfo(requestId);
        if (request != null) {
            // 创建一个固定大小的线程池
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            // 异步执行获取各个信息的任务
            CompletableFuture<LuntaiOrder> orderInfoFuture = CompletableFuture.supplyAsync(() -> getOrderByRequest(1, requestId), executorService);
            CompletableFuture<LuntaiStore> storeInfoFuture = CompletableFuture.supplyAsync(() -> getStoreByStoreId(request.getStoreId()), executorService);
            CompletableFuture<LuntaiTyre> tyreInfoFuture = CompletableFuture.supplyAsync(() -> getTyreByCarId(request.getCarId()), executorService);
            CompletableFuture<List<LuntaiUserTyre>> tyreListFuture = CompletableFuture.supplyAsync(() -> getRequestTyreListByRequestId(requestId), executorService);
            CompletableFuture<LuntaiUserCar> carInfoFuture = CompletableFuture.supplyAsync(() -> getCarById(request.getCarId()), executorService);
            // 等待所有异步任务执行完成并获取结果
            CompletableFuture.allOf(orderInfoFuture, storeInfoFuture, tyreInfoFuture, tyreListFuture, carInfoFuture).join();
            // 聚合结果
            PolicyExtensionRequestInfoDto policyExtensionRequestInfoDto = new PolicyExtensionRequestInfoDto();
            policyExtensionRequestInfoDto.setCarInfo(carInfoFuture.join());
            policyExtensionRequestInfoDto.setStoreInfo(storeInfoFuture.join());
            policyExtensionRequestInfoDto.setRequestInfo(request);
            policyExtensionRequestInfoDto.setOrderInfo(orderInfoFuture.join());
            policyExtensionRequestInfoDto.setTyre(tyreInfoFuture.join());
            policyExtensionRequestInfoDto.setTyreInfo(tyreListFuture.join());
            // 关闭线程池
            executorService.shutdown();
            try {
                // 等待线程池中所有任务完成，最多等待10秒
                if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
            }
            return policyExtensionRequestInfoDto;
        } else {
            return null;
        }
    }


    @Override
    public List<LuntaiStore> getStoreList(LuntaiStore store) {
//        if (store.getLatitude() == null || store.getLongitude() == null) {
//            return new ArrayList<>();
//        }
//        Integer distance = luntaiMapper.getDistance();
//        store.setIsdelete(distance);
        return luntaiMapper.getStoreList(store);
    }

    @Override
    public List<AreaList> geAllArea() {
        // 查询所有区域信息
        List<SysArea> areas = luntaiMapper.getAreaList();

        // 防止 areas 为 null
        if (areas == null || areas.isEmpty()) {
            return new ArrayList<>(); // 返回空列表
        }

        // 创建一个 map 存储父子关系
        Map<Integer, SysArea> areaMap = new HashMap<>();
        for (SysArea area : areas) {
            areaMap.put(area.getDistrictId(), area);
        }
        // 构建父子级关系
        for (SysArea area : areas) {
            if (area.getParentId() != null) {
                SysArea parentArea = areaMap.get(area.getParentId());
                if (parentArea != null) {
                    // 确保父区域的 sonList 已初始化
                    if (parentArea.getSonList() == null) {
                        parentArea.setSonList(new ArrayList<>());
                    }
                    parentArea.getSonList().add(area); // 将当前区域作为子区域加入父区域的 sonList 中
                }
            }
        }
        // 构建 AreaList
        List<AreaList> areaLists = new ArrayList<>();
        for (SysArea area : areas) {
            if (area.getLevelType() == 1) {  // 如果是省级区域（没有父级区域）
                AreaList areaList = new AreaList();
                areaList.setProvince(area.getName()); // 省级区域的 name 设置为 province
                List<String> cities = new ArrayList<>();
                // 遍历该省的子区域
                if (area.getSonList() != null) {  // 确保 sonList 不为 null
                    for (SysArea cityArea : area.getSonList()) {
                        cities.add(cityArea.getName()); // 将子区域的 name 加入 city 列表
                    }
                }
                areaList.setCity(cities);
                areaLists.add(areaList); // 添加到返回的列表中
            }
        }

        // 返回 areaLists 作为最终结果
        return areaLists;
    }


    @Override
    public List<LuntaiMessage> getMessageList() {
        return luntaiMapper.getMessageList(MemberUtil.getUserId());
    }

    @Override
    public void editMessage(LuntaiMessage message) {
        luntaiMapper.editMessage(message);
    }

    @Override
    public List<LuntaiIntroduce> getAllIntroduce() {
        return luntaiMapper.getAllIntroduce();
    }

    @Override
    public List<LuntaiCoupons> getCoupons() {
        return luntaiMapper.getCoupons(MemberUtil.getUserId());
    }

    @Override
    public List<LuntaiNews> getNews() {
        return luntaiMapper.getNews();
    }

    @Override
    public LuntaiNews getNewsInfo(Integer newsId) {
        luntaiMapper.addViewCount(newsId);
        return luntaiMapper.getNewsById(newsId);
    }

    @Override
    public void rescueApplication(LuntaiRescueApplication application) {
        application.setUseId(MemberUtil.getUserId());
        luntaiMapper.rescueApplication(application);
        createOrder(3, application.getId(), application.getStoreId(), MemberUtil.getUserId());
    }

    @Override
    public void editRescueApplication(LuntaiRescueApplication application) {
        luntaiMapper.editRescueApplication(application);
    }

    @Override
    public List<LuntaiRescueApplicationDto> getRescueApplicationList(Integer status) {
        Integer userId = MemberUtil.getUserId();
        return luntaiMapper.getRescueApplicationList(userId, status);
    }

    @Override
    public RescueApplicationDto getRescueApplicationInfoById(Integer applicationId) {
        LuntaiRescueApplication luntaiRescueApplication = luntaiMapper.getRescueApplicationInfoById(applicationId);
        if (luntaiRescueApplication == null) {
            return null;
        }
        // 创建线程池，避免默认的 ForkJoinPool 影响全局线程
        ExecutorService executor = Executors.newFixedThreadPool(4);
        try {
            // 异步查询
            CompletableFuture<LuntaiStore> storeFuture = CompletableFuture.supplyAsync(
                    () -> getStoreByStoreId(luntaiRescueApplication.getStoreId()), executor
            );

            CompletableFuture<LuntaiUserCar> carFuture = CompletableFuture.supplyAsync(
                    () -> getCarById(luntaiRescueApplication.getCarId()), executor
            );

            CompletableFuture<LuntaiTyre> tyreFuture = CompletableFuture.supplyAsync(
                    () -> getTyreByCarId(luntaiRescueApplication.getCarId()), executor
            );

            CompletableFuture<LuntaiOrder> orderFuture = CompletableFuture.supplyAsync(
                    () -> getOrderByRequest(3, applicationId), executor
            );
            // 等待所有任务完成
            CompletableFuture.allOf(storeFuture, carFuture, tyreFuture, orderFuture).join();
            // 获取结果
            RescueApplicationDto applicationDto = new RescueApplicationDto();
            applicationDto.setApplicationInfo(luntaiRescueApplication);
            applicationDto.setStoreInfo(storeFuture.get());
            applicationDto.setCarInfo(carFuture.get());
            applicationDto.setTyre(tyreFuture.get());
            applicationDto.setOrderInfo(orderFuture.get());
            return applicationDto;
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
            return null;
        } finally {
            // 关闭线程池
            executor.shutdown();
        }
    }

    @Override
    public List<CarsListDto> getCarSummarizeInformation(UserCarsDto dto) {
        dto.setId(MemberUtil.getUserId());
        return luntaiMapper.getCarSummarizeInformation(dto);
    }

    @Override
    public void storeApplication(LuntaiStoreApplication application) {
        String phone = application.getPhone();
        Integer count = luntaiMapper.getStoreApplicationByPhone(phone);
        if (count > 0) {
            Asserts.fail("当前申请已存在，等待审核");
            return;
        }
        if (application.getPhone() == null) {
            Asserts.fail("手机号不能为空");
            return;
        }
        SysUser adminInfoByUserPhone = getAdminInfoByUserPhone(application.getPhone());
        if (adminInfoByUserPhone != null) {
            Asserts.fail("当前手机号已存在");
            return;
        }
        application.setUserId(MemberUtil.getUserId());
        luntaiMapper.storeApplication(application);
        if (getAuditStatus(2)) {
            application.setStatus(1);
            auditStoreApplication(application);
        } else {
            sendNoticePush(application);
        }
    }

    private void sendNoticePush(LuntaiStoreApplication application) {
        List<LuntaiUser> admins = luntaiMapper.getSuperAdmin();
        for (LuntaiUser admin : admins) {
            OfaPushVO ofaPushVO = new OfaPushVO();
            ofaPushVO.setPhone(application.getPhone());
            ofaPushVO.setStoreName(application.getStoreName());
            ofaPushVO.setOpenId(admin.getOpneid());
            ofaPushVO.setAuditInfo("您有一条审核信息，需要审核");
            sendAuditNotice(ofaPushVO);
        }
    }

    @Override
    public List<LuntaiStoreApplication> getStoreApplicationList() {
        return luntaiMapper.getStoreApplicationList(MemberUtil.getUserId());
    }

    @Override
    public String uploadPic(MultipartFile file) {
        if (file.isEmpty()) {
            throw new RuntimeException("上传的文件不能为空！");
        }
        try {
            // 确保存储目录存在
            Files.createDirectories(Paths.get(tyreAddress));
            // 生成唯一文件名，防止文件名冲突
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = UUID.randomUUID().toString().replace("-", "") + extension;

            // 目标文件
            File destinationFile = new File(tyreAddress, newFileName);
            file.transferTo(destinationFile);
            // 返回文件访问 URL
            return webUrl + "image/" + newFileName;
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败！", e);
        }
    }

    @Override
    public List<LuntaiRescueType> getRescueTypeList() {
        return luntaiMapper.getRescueTypeList();
    }

    @Override
    public List<LuntaiUserTyre> getTyreListByCarId(Integer carId) {
        return luntaiMapper.getTyreListByCarId(carId);
    }

    @Override
    public Boolean checkIsApplyStore() {
        return 0 < luntaiMapper.checkIsApplyStore(MemberUtil.getUserId());
    }

    @Override
    public List<LuntaiStoreApplication> getStoreApplyResult() {
        return luntaiMapper.getStoreApplyResult(MemberUtil.getUserId());
    }

    @Override
    public List<LuntaiStore> getStoreByLocation(LuntaiStore luntaiStore) {
        Integer distance = luntaiMapper.getDistance();
        luntaiStore.setIsdelete(distance);
        return luntaiMapper.getStoreByLocation(luntaiStore);

    }

    @Override
    public Map<String, String> getLocationByCoords(String coords) throws IOException {
        String json = LachesismTools.sendGet("https://api.map.baidu.com/reverse_geocoding/v3/?ak=gDrnUUVv8eC1ryse6GX9wQ3r7XXv8CaN&extensions_poi=1&output=json&location=" + coords);
        JSONObject jsonResponse = JSON.parseObject(json);
        JSONObject result = jsonResponse.getJSONObject("result");
        JSONObject addressComponent = result.getJSONObject("addressComponent");
        // 提取字段
        String formattedAddress = result.getString("formatted_address");
        String province = addressComponent.getString("province");
        String city = addressComponent.getString("city");
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        map.put("city", city);
        map.put("province", province);
        map.put("formatted_address_poi", formattedAddress);
        return map;
    }


    @Override
    public List<String> getQrcodeInfo(String barcode) {
        String url = "http://221.1.200.234:9008/UMES/Interface/GetTyreInfoByBarcode?barcocde=" + barcode;
        List<String> result = new ArrayList<>();

        for (int retryCount = 0; retryCount < MAX_RETRIES; retryCount++) {
            try {
                // 发送 GET 请求获取 JSON 数据
                String response = LachesismTools.sendGet(url);
                if (response == null || response.isEmpty()) {
                    throw new Exception("空响应");
                }
                // 解析 JSON 响应
                JSONObject jsonResponse = JSON.parseObject(response);
                if (jsonResponse.getInteger("code") == 200) {
                    JSONObject dataObject = jsonResponse.getJSONObject("data");
                    JSONArray dtArray = dataObject.getJSONArray("dt");

                    if (dtArray != null && !dtArray.isEmpty()) {
                        JSONObject tyreInfo = dtArray.getJSONObject(0);
                        result.add("spcnm: " + tyreInfo.getString("spcnm"));
                        result.add("patnm: " + tyreInfo.getString("patnm"));
                        result.add("dot: " + tyreInfo.getString("dot"));
                        result.add("brnm: " + tyreInfo.getString("brnm"));
                        result.add("erpid: " + tyreInfo.getString("erpid"));
                        result.add("scmnm: " + tyreInfo.getString("scmnm"));
                    }
                    return result;  // 成功获取数据后返回
                } else {
                    throw new Exception("响应错误，code: " + jsonResponse.getInteger("code"));
                }
            } catch (Exception e) {
                // 如果是最后一次重试，则不再重试
                if (retryCount == MAX_RETRIES - 1) {
                    System.err.println("重试失败，超过最大重试次数");
                } else {
                    System.err.println("请求失败，正在重试 (" + (retryCount + 1) + "/" + MAX_RETRIES + "): " + e.getMessage());
                    try {
                        Thread.sleep(RETRY_INTERVAL);  // 等待重试
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();  // 恢复中断状态
                    }
                }
            }
        }
        return result;  // 返回空结果
    }

    @Override
    public void auditStoreApplication(LuntaiStoreApplication luntaiStoreApplication) {
        Integer status = luntaiStoreApplication.getStatus();
        if (status != null) {
            if (status == 1) {
                generateAdminAndStore(luntaiStoreApplication);
            }
            if (status != 0) {
                sendMessage(luntaiStoreApplication);
                addAuditLog(luntaiStoreApplication.getStatus() == 1 ? 1 : 0, getAdminInfoByUserPhone(MemberUtil.getMemberPhone()), luntaiStoreApplication.getId(), 2);
            }
        }
        luntaiMapper.updateLuntaiStoreApplication(luntaiStoreApplication);

    }

//    @Override
//    public void InstallTyres(TyreInstallParam param) {
//        LuntaiTyreInstallRequest luntaiTyreInstallRequest = new LuntaiTyreInstallRequest();
//        luntaiTyreInstallRequest.setCarId(param.getCarId());
//        luntaiTyreInstallRequest.setUserId(param.getUserId());
//        luntaiMapper.addTyreInstallRequest(luntaiTyreInstallRequest);
//        Integer requestId = luntaiTyreInstallRequest.getId();
//        List<LuntaiTyreInstallLog> tyres = param.getLuntaiTyreInstallLogList();
//        if (tyres == null || tyres.isEmpty()) {
//            Asserts.fail("轮胎安装请求列表不能为空");
//            return;
//        }
//        // 提取 code 列表
//        List<String> codes = tyres.stream()
//                .map(LuntaiTyreInstallLog::getCode)
//                .collect(Collectors.toList());
//        if (codes.isEmpty()) {
//            Asserts.fail("所有轮胎安装日志的 Code 均为空");
//            return;
//        }
//        // 检查数据库是否已有相同 Code
//        List<String> existingCodes = luntaiMapper.checkCodeEx(codes);
//        if (existingCodes != null && !existingCodes.isEmpty()) {
//            Asserts.fail("以下 Code 已存在: " + String.join(", ", existingCodes));
//            return;
//        }
//        for (LuntaiTyreInstallLog tyre : tyres) {
//            tyre.setRequestId(requestId);
//        }
//        luntaiMapper.addTyreInstallRequestTyres(tyres);
//    }


    @Override
    public Integer addTyreInstallRequest(LuntaiTyreInstallRequest request) {
        System.out.println("================添加轮胎安装信息================");
        System.out.println(request);
        System.out.println("================安装信息================");
        luntaiMapper.addTyreInstallRequest(request);
        createOrder(1, request.getId(), request.getStoreId(), request.getUserId());
        LuntaiTyre tyreBrand = luntaiMapper.getTyreBrandById(request.getTyreBrandId());
        LuntaiUserCar luntaiUserCar = new LuntaiUserCar();
        luntaiUserCar.setId(request.getCarId());
        luntaiUserCar.setBrandId(request.getTyreBrandId());
        luntaiUserCar.setStoreId(request.getStoreId());
        luntaiUserCar.setBrand(tyreBrand.getName());
        luntaiMapper.updateCar(luntaiUserCar);
        if (getAuditStatus(1)) {
            finishTyreInstallRequest(request.getId());
        }
        return request.getId();
    }

    private void finishTyreInstallRequest(Integer requestId) {
        LuntaiOrder order = getOrderByRequest(1, requestId);
        luntaiMapper.finishOrder(order.getId());
        luntaiMapper.finishInstallRequest(requestId);
    }

    @Override
    public void deleteTyreInstallRequestLog(Integer requestId) {
        luntaiMapper.deleteTyreInstallRequestLog(requestId);
        luntaiMapper.deleteDeleteOrder(getOrderByRequest(1, requestId).getId());
    }

    private void saveVideoUploadLog(String fileName) {
        luntaiMapper.saveVideoUploadLog(fileName, MemberUtil.getUserId(), MemberUtil.getMemberPhone());
    }

    @Override
    public Map<String, String> uploadVideo(MultipartFile file) {
        HashMap<String, String> urlMap = new HashMap<>();
        UmsMember userInfo = MemberUtil.getUserInfo();
        if (file.isEmpty()) {
            Asserts.fail("上传失败，文件为空");
        }
        // 获取原始文件名和扩展名
        String originalFilename = file.getOriginalFilename();
        String suffix = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        } else {
            Asserts.fail("上传失败，无法获取文件扩展名");
        }
        // 生成文件名并拼接后缀
        String fileName = userInfo.getPhone() + "_" +
                LachesismTools.getTime("yyyyMMddHHmm") + "_" +
                LachesismTools.generateRandomCode(4) + suffix;
        String directoryPath = "/project/media/video/";
//        String directoryPath = "/Users/yuno/Documents/";
        File dir = new File(directoryPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String filePath = directoryPath + fileName;
        saveVideoUploadLog(filePath);
        try {
            file.transferTo(new File(filePath));
        } catch (IOException e) {
            e.printStackTrace();
            Asserts.fail("上传失败：" + e.getMessage());
        }
        urlMap.put("webUrl", webUrl + "video/" + fileName);
        urlMap.put("path", filePath);
        return urlMap;
    }

    @Override
    public void addTyreInstallRequestTyres(List<LuntaiTyreInstallLog> tyres) {
        if (tyres == null || tyres.isEmpty()) {
            Asserts.fail("轮胎安装请求列表不能为空1");
            return;
        }
        if (tyres.get(0) == null) {
            Asserts.fail("轮胎安装请求列表不能为空");
            return;
        }
        // 过滤掉 id 不为空的元素，以及 null、code 为空的元素
        tyres.removeIf(tyre -> tyre == null || tyre.getId() != null ||
                tyre.getCode() == null || tyre.getCode().trim().isEmpty());
        if (tyres.isEmpty()) {
            Asserts.fail("该车辆已注册");
            return;
        }
        // 提取去重后的 code 列表
        Set<String> codes = tyres.stream()
                .map(LuntaiTyreInstallLog::getCode)
                .collect(Collectors.toSet());
        if (codes.isEmpty()) {
            Asserts.fail("所有轮胎安装的 Code 均为空");
            return;
        }
        // 检查数据库是否已有相同 Code
        List<String> existingCodes = luntaiMapper.checkCodeEx(new ArrayList<>(codes));
        if (existingCodes != null && !existingCodes.isEmpty()) {
            Asserts.fail("以下 Code 已存在: " + String.join(", ", existingCodes));
            return;
        }
        // 插入数据库
        luntaiMapper.addTyreInstallRequestTyres(tyres);
    }

    @Override
    public List<TyreInstallLogDto> getTyreListByCarId2(Integer carId) {
        List<TyreInstallLogDto> tyreListByCarId2 = luntaiMapper.getTyreListByCarId2(carId);
        for (TyreInstallLogDto tyreInstallLogDto : tyreListByCarId2) {
            if (tyreInstallLogDto.getInstallationTime() != null) {
                // 获取当前时间
                Calendar calendar = Calendar.getInstance();
                // 计算 1 年前的时间
                calendar.add(Calendar.YEAR, -1);
                Date oneYearAgo = calendar.getTime();
                // 如果安装时间早于 1 年前，设置 isReparation 为 2
                if (tyreInstallLogDto.getInstallationTime().before(oneYearAgo)) {
                    tyreInstallLogDto.setIsReparation(2);
                }
            }
        }
        return tyreListByCarId2;
    }

    @Override
    public List<InstallRequestDto> getUninstallRequests() {
        List<Integer> notInstallId = luntaiMapper.getNotInstallId();
        if (notInstallId != null && !notInstallId.isEmpty()) {
            return luntaiMapper.getInstallRequests(notInstallId);
        }
        return Collections.emptyList();
    }

    @Override
    public List<TyreInstallListDto> getTyreInstallRequest(Integer status) {
        List<TyreInstallListDto> tyreInstallRequest = luntaiMapper.getTyreInstallRequest(MemberUtil.getUserId(), status,null);
        for (TyreInstallListDto tyreInstallListDto : tyreInstallRequest) {
            tyreInstallListDto.setTyreList(luntaiMapper.getTyreListByRequestId(tyreInstallListDto.getId()));
        }
        return tyreInstallRequest;
    }

    @Override
    public ResponsePage<TyreInstallListDto> getTyreInstallRequestOnPage(Integer status, Integer pageNum, Integer pageSize,String licensePlate) {
        PageHelper.startPage(pageNum, pageSize);
        List<TyreInstallListDto> tyreInstallRequest = luntaiMapper.getTyreInstallRequest(MemberUtil.getUserId(), status,licensePlate);
        for (TyreInstallListDto tyreInstallListDto : tyreInstallRequest) {
            tyreInstallListDto.setTyreList(luntaiMapper.getTyreListByRequestId(tyreInstallListDto.getId()));
        }
        return ResponsePage.restPage(new PageInfo<>(tyreInstallRequest));
    }


    @Override
    public List<TyreInstallListDto> getInstallRequestListByLicensePlate(Integer status, String licensePlate) {
        List<TyreInstallListDto> tyreInstallRequest = luntaiMapper.getInstallRequestListByLicensePlate(status, licensePlate);
        for (TyreInstallListDto tyreInstallListDto : tyreInstallRequest) {
            tyreInstallListDto.setTyreList(luntaiMapper.getTyreListByRequestId(tyreInstallListDto.getId()));
        }
        return tyreInstallRequest;
    }

    @Override
    public List<TyreInstallListDto> getRequestListByStoreId(Integer storeId, Integer status) {
        List<TyreInstallListDto> tyreInstallRequest = new ArrayList<>();
        if (storeId == null || storeId < 1) {
            tyreInstallRequest = luntaiMapper.getRequestListByStoreId2(status);
        } else {
            tyreInstallRequest = luntaiMapper.getRequestListByStoreId(storeId, status);
        }
        for (TyreInstallListDto tyreInstallListDto : tyreInstallRequest) {
            tyreInstallListDto.setTyreList(luntaiMapper.getTyreListByRequestId(tyreInstallListDto.getId()));
        }
        return tyreInstallRequest;
    }

    @Override
    public void claimsApplication(LuntaiClaimsRequest request) {
        LuntaiClaimsRequest requestInfo = luntaiMapper.getClaimRequestByTyreId(request.getTyreId());
        if (requestInfo != null) {
            Asserts.fail("此轮胎已申请过");
        }
        request.setUserId(MemberUtil.getUserId());
        luntaiMapper.claimApplication(request);
        Integer storeId = luntaiMapper.getTyreInstallInfo(request.getTyreId());
        Integer requestId = request.getId();
        createOrder(4, requestId, storeId, request.getUserId());
    }

    @Override
    public ResponsePage<ClaimRequestDto> getClaimApplicationList(ClaimRequestDto request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<ClaimRequestDto> claimApplicationList = luntaiMapper.getClaimApplicationList(request);
        return ResponsePage.restPage(new PageInfo<>(claimApplicationList));
    }

    private OfaPushVO sendAdminMessageByClaims(String phone, Integer type, String openId) {
        OfaPushVO ofaPushVO = new OfaPushVO();
        String result = "审核通过";
        String result2 = "通过";
        if (type.equals(3)) {
            result = "审核驳回";
            result2 = "驳回";
        }
        ofaPushVO.setResult(result);
        ofaPushVO.setRemake(phone + "申请的理赔已" + result2);
        ofaPushVO.setOpenId(openId);
        ofaPushVO.setAuditType(result2);
        System.out.println("发给用户：" + phone + " openId为:" + openId + " 审核结果为：" + result);
        return ofaPushVO;
    }

    private OfaPushVO sendAdminMessageByClaims(Integer userId, Integer type) {
        OfaPushVO ofaPushVO = new OfaPushVO();
        UmsMember userInfo = memberMapper.getUserInfo(userId);
        String result = "审核通过";
        String result2 = "通过";
        if (type.equals(3)) {
            result = "审核驳回";
            result2 = "驳回";
        }
        ofaPushVO.setResult(result);
        ofaPushVO.setRemake("您申请的理赔已" + result2);
        ofaPushVO.setOpenId(userInfo.getOpneid());
        ofaPushVO.setAuditType(result2);
        System.out.println("发给用户：" + userInfo.getPhone() + " openId为:" + userInfo.getOpneid() + " 审核结果为：" + result);
        return ofaPushVO;
    }

    @Override
    public void updateClaimsApplication(LuntaiClaimsRequest request) {

        LuntaiClaimsRequest claimRequest = luntaiMapper.getClaimRequest(request.getId());
        UmsMember memberInfo = memberMapper.getMemberInfo(MemberUtil.getMemberPhone());
        SysUser adminInfo = getAdminInfoByUserPhone(MemberUtil.getMemberPhone());

        List<String> openIds = memberMapper.getGetAllAdminOpenIds();
        UmsMember userInfo = memberMapper.getUserInfo(claimRequest.getUserId());
        if (request.getCode() != null) {
            Integer count = luntaiMapper.checkCodeEx2(request.getCode());
            if (count > 0) {
                Asserts.fail("该 Code 已存在");
                return;
            }
        }

        //2 申请状态为 2 或者 3 才修改状态
        if (request.getStatus() != null) {
            addAuditLog(request.getStatus() == 2 ? 1 : 0, adminInfo, request.getId(), 1);
            if (LachesismTools.isEmpty(memberInfo) || !memberInfo.getRole().equals(2)) {
                Asserts.fail("暂无权限");
                return;
            }
            if (LachesismTools.isEmpty(adminInfo)) {
                Asserts.fail("你不是门店管理员");
                return;
            }

            request.setAdminId(Math.toIntExact(adminInfo.getUserId()));
            switch (request.getStatus()) {
                case 2: // 同意
                    // 修改订单状态为成功
                    request.setIsAudit(1);
                    updateClaimOrder(request.getId(), 1, Math.toIntExact(adminInfo.getUserId()));
                    AsyncUtil.executeAsync(() -> {
                        for (String openId : openIds) {
                            sendAuditResult2(sendAdminMessageByClaims(userInfo.getPhone(), 1, openId));
                        }
                        sendAuditResultToUser(sendAdminMessageByClaims(request.getUserId(), 1));
                    });
                    break;
                case 3: // 驳回
                    //修改订单状态为取消getCarInfoByLicensePlat
                    request.setIsAudit(1);
                    updateClaimOrder(request.getId(), 3, Math.toIntExact(adminInfo.getUserId()));
                    AsyncUtil.executeAsync(() -> {
                        for (String openId : openIds) {
                            sendAuditResult2(sendAdminMessageByClaims(userInfo.getPhone(), 3, openId));
                        }
                        sendAuditResultToUser(sendAdminMessageByClaims(request.getUserId(), 3));

                    });
                    break;
            }
            if (request.getStatus().equals(2)) {
                //如果是同意的话，就去替换老轮胎
                Integer tyreId = request.getTyreId();
                LuntaiTyreInstallLog tyre = luntaiMapper.getTyreById(tyreId);
                LuntaiTyreInstallLog luntaiTyreInstallLog = new LuntaiTyreInstallLog();
                BeanUtil.copyProperties(tyre, luntaiTyreInstallLog);
                luntaiTyreInstallLog.setIsReparation(1);
                luntaiTyreInstallLog.setDot(request.getDotImg());
                luntaiTyreInstallLog.setPatnm(request.getPattenImg());
                luntaiTyreInstallLog.setSpcnm(request.getDriveLicenseImg());
                luntaiTyreInstallLog.setCode(request.getCode());
                luntaiMapper.replaceTryeByClaims(luntaiTyreInstallLog);
                luntaiMapper.cancelOldTyre(tyreId);
            }

        }
        luntaiMapper.updateClaimsApplication(request);


    }

//    @Override
//    public ClaimDetailInfoDto getDetailInfoByClaimId(Integer requestId) {
//        ClaimDetailInfoDto detailInfoDto = new ClaimDetailInfoDto();
//        LuntaiClaimsRequest claimRequest = luntaiMapper.getClaimRequest(requestId);
//        //获取申请详情
//        detailInfoDto.setRequest(claimRequest);
//        LuntaiTyreInstallLog tyre = luntaiMapper.getTyreById(claimRequest.getTyreId());
//        detailInfoDto.setBeforeTyreInfo(tyre);
//        //获取轮胎安装之前记录
//        detailInfoDto.setAfterTyreInfo(luntaiMapper.getAfterTyreInfo(claimRequest.getCode()));
//        //获取轮胎之后记录
//        detailInfoDto.setQrcode("data:image/png;base64," + generateQRCodeBase64(String.valueOf(requestId)));
//        LuntaiTyreInstallRequest tyreInstallRequestInfo = luntaiMapper.getTyreInstallRequestInfo(tyre.getRequestId());
//        detailInfoDto.setCarInfo(luntaiMapper.getCarById(tyreInstallRequestInfo.getCarId()));
//        LuntaiTyreInstallRequest request = luntaiMapper.getInstallTyreRequestByTyreId(tyre.getId());
//        detailInfoDto.setStoreInfo(luntaiMapper.getStoreByStoreId(request.getStoreId()));
//        detailInfoDto.setOrderSn(luntaiMapper.getOrderSn(requestId, 4));
//        return detailInfoDto;
//    }

    public void checkConfig(Boolean result) {

    }

    @Override
    public InstallTyreDetailInfoDto getInstallTyreInfoByRequestId(Integer requestId) {
        InstallTyreDetailInfoDto installTyreDetailInfoDto = new InstallTyreDetailInfoDto();
        LuntaiTyreInstallRequest request = luntaiMapper.getTyreInstallRequestInfo(requestId);
        installTyreDetailInfoDto.setRequest(request);
        installTyreDetailInfoDto.setCarInfo(luntaiMapper.getCarById(request.getCarId()));
        installTyreDetailInfoDto.setTyreList(luntaiMapper.getTyreListByRequestId(request.getId()));
        installTyreDetailInfoDto.setStoreInfo(luntaiMapper.getStoreByStoreId(request.getStoreId()));
        installTyreDetailInfoDto.setQrcode("data:image/png;base64," + generateQRCodeBase64(String.valueOf(requestId)));
        installTyreDetailInfoDto.setOrderSn(luntaiMapper.getOrderSn(requestId, 1));
        return installTyreDetailInfoDto;
    }

    @Override
    public LuntaiStoreAdminDto getStoreInfoByAdmin() {
        SysUser adminInfo = luntaiMapper.getAdminInfo(MemberUtil.getMemberPhone());
        LuntaiStoreAdminDto storeInfoByAdmin = luntaiMapper.getStoreInfoByAdmin(Math.toIntExact(adminInfo.getUserId()));
        storeInfoByAdmin.setUndoCount(luntaiMapper.getNotInstallCount(storeInfoByAdmin.getId()));//通过门店id查询待处理的安装数量
        storeInfoByAdmin.setInstallCount(luntaiMapper.getInstallTyreCountByStoreId(storeInfoByAdmin.getId()));
        storeInfoByAdmin.setHelpCount(luntaiMapper.getHelpCountByStoreId(storeInfoByAdmin.getId()));
        storeInfoByAdmin.setReplaceCount(luntaiMapper.getReplaceCountByStoreId(storeInfoByAdmin.getId()));
        return storeInfoByAdmin;
    }

//    @Override
//    public List<LuntaiStoreApplication> getStoreListByAdmin(LuntaiStoreApplication application) {
//        return luntaiMapper.getStoreListByAdmin(application);
//    }

    @Override
    public ResponsePage<LuntaiStoreApplication> getStoreListByAdmin(LuntaiStoreApplication application) {
        PageHelper.startPage(application.getPageNum(), application.getPageSize());
        List<LuntaiStoreApplication> storeListByAdmin = luntaiMapper.getStoreListByAdmin(application);
        return ResponsePage.restPage(new PageInfo<>(storeListByAdmin));
    }

    @Override
    @SneakyThrows
    public Map<String, Integer> claimFourInfo() {
        // 定义四个异步任务
        CompletableFuture<Integer> applicationFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimApplicationCount());
        CompletableFuture<Integer> auditFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimUnAuditCount());
        CompletableFuture<Integer> refuseFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimRefuseCount());
        CompletableFuture<Integer> successFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimSuccessCount());
        CompletableFuture<Integer> todo = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimTodo());
        // 等待所有任务完成
        CompletableFuture.allOf(applicationFuture, auditFuture, refuseFuture, successFuture).join();
        // 组装结果
        Map<String, Integer> map = new HashMap<>();
        map.put("application", applicationFuture.get());//全部✅
        map.put("audit", auditFuture.get());//带安装✅
        map.put("todo", todo.get());//待处理✅
        map.put("refuse", refuseFuture.get());
        map.put("success", successFuture.get());
        return map;
    }

    @Override
    @SneakyThrows
    public Map<String, Integer> claimFourInfoOnUser(Integer userId) {
        // 定义四个异步任务
        CompletableFuture<Integer> applicationFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimApplicationCountOnUser(userId));
        CompletableFuture<Integer> auditFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimUnAuditCountOnUser(userId));
        CompletableFuture<Integer> refuseFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimRefuseCountOnUser(userId));
        CompletableFuture<Integer> successFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimSuccessCountOnUser(userId));
        CompletableFuture<Integer> todo = AsyncUtil.executeAsync(() -> luntaiMapper.getClaimTodoOnUser(userId));
        // 等待所有任务完成
        CompletableFuture.allOf(applicationFuture, auditFuture, refuseFuture, successFuture).join();
        // 组装结果
        Map<String, Integer> map = new HashMap<>();
        map.put("application", applicationFuture.get());//全部✅
        map.put("audit", auditFuture.get());//带安装✅
        map.put("todo", todo.get());//待处理✅
        map.put("refuse", refuseFuture.get());
        map.put("success", successFuture.get());
        return map;
    }


    @Override
    @SneakyThrows
    public Map<String, Integer> totalThreeInfo() {
        // 定义四个异步任务
        CompletableFuture<Integer> unAuditStoreCount = AsyncUtil.executeAsync(() -> luntaiMapper.getUnAuditStoreCount());
        CompletableFuture<Integer> unAuditClaimCount = AsyncUtil.executeAsync(() -> luntaiMapper.getUnAuditClaimCount());
        CompletableFuture<Integer> tyreInstallCount = AsyncUtil.executeAsync(() -> luntaiMapper.getTyreInstallCount());
        // 等待所有任务完成
        CompletableFuture.allOf(unAuditStoreCount, unAuditClaimCount, tyreInstallCount).join();
        // 组装结果
        Map<String, Integer> map = new HashMap<>();
        map.put("storeCount", unAuditStoreCount.get());
        map.put("claimCount", unAuditClaimCount.get());
        map.put("install", tyreInstallCount.get());
        return map;
    }


    @SneakyThrows
    @Override
    public Map<String, Integer> storeFourInfo() {
        // 定义四个异步任务
        CompletableFuture<Integer> applicationFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getStoreApplicationCount());
        CompletableFuture<Integer> auditFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getUnAuditCount());
        CompletableFuture<Integer> refuseFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getRefuseCount());
        CompletableFuture<Integer> successFuture = AsyncUtil.executeAsync(() -> luntaiMapper.getSuccessCount());
        // 等待所有任务完成
        CompletableFuture.allOf(applicationFuture, auditFuture, refuseFuture, successFuture).join();
        // 组装结果
        Map<String, Integer> map = new HashMap<>();
        map.put("application", applicationFuture.get());
        map.put("audit", auditFuture.get());
        map.put("refuse", refuseFuture.get());
        map.put("success", successFuture.get());
        return map;
    }


    @Override
    public LuntaiStoreApplicationDto getStoreApplicationById(Integer applicationId) {
        return luntaiMapper.getStoreApplicationById(applicationId);
    }

    @Override
    public List<LuntaiExampleImage> getExampleImg(Integer type) {
        return luntaiMapper.getExampleImg(type);
    }

    @Override
    public Boolean getAuditState(Integer type) {
        return getAuditState(type);
    }

    @Override
    public ResponseResult withdrawStore(String phone) {
        if (luntaiMapper.getExistOrder(phone) > 0) {
            return ResponseResult.failed("已存在订单不支持删除");
        } else {
            //删除管理员
            luntaiMapper.deleteAdmin(phone);
            //删除门店
            luntaiMapper.deleteStore(phone);
//            //删除申请
            luntaiMapper.deleteStoreApplication(phone);
            //恢复身份
            luntaiMapper.recoverRole(phone);
            return ResponseResult.success(null, "已撤回");
        }
    }

    @Override
    public void updateMenu(SysMenu menu) {
        luntaiMapper.updateMenu(menu);
    }


    public void updateClaimOrder(Integer claimId, Integer status, Integer adminId) {
        luntaiMapper.updateClaimOrder(claimId, status, adminId);
    }

    public SysUser getAdminInfoByUserPhone(String phone) {
        return luntaiMapper.getAdminInfo(phone);
    }

    @Override
    public void editTyreInstallRequest(LuntaiTyreInstallRequest request) {
        if (request.getStatus() != null && request.getStatus() == 2) {
            finishTyreInstallRequest(request.getId());
        }
        luntaiMapper.editTyreInstallRequest(request);
    }


    public void generateAdminAndStore(LuntaiStoreApplication luntaiStoreApplication) {
        // 获取申请信息
        LuntaiStoreApplication applicationInfo = luntaiMapper.selectLuntaiStoreApplicationById(luntaiStoreApplication.getId());
        Integer userId = applicationInfo.getUserId();

        // 获取用户信息
        LuntaiUser luntaiUser = luntaiMapper.selectLuntaiUserById(userId);
        if (luntaiUser == null) {
            Asserts.fail("用户信息不存在");
        }
        // 校验是否已存在该管理员账号
        SysUser sysUser1 = luntaiMapper.selectUserByUserName(luntaiUser.getUsername());
        if (sysUser1 != null) {
            Asserts.fail("管理员已存在，当前用户已经申请店铺不可重复申请");
        }
        // 设置用户备注为门店管理员
        luntaiUser.setRemake(applicationInfo.getStoreName() + "门店管理员");
        luntaiUser.setRole(3);
        luntaiMapper.updateLuntaiUser(luntaiUser);

        // 创建管理员账号
        SysUser sysUser = new SysUser();
        UmsMember userInfo = MemberUtil.getUserInfo();
        sysUser.setUserName(luntaiUser.getUsername());
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encoded = passwordEncoder.encode(luntaiUser.getPhone());
        sysUser.setPassword(encoded);
        sysUser.setNickName(applicationInfo.getStoreName() + "门店");
        sysUser.setPhonenumber(luntaiUser.getPhone());
        sysUser.setAvatar(luntaiUser.getIcon());
        sysUser.setCreateBy(userInfo.getUsername());
        sysUser.setRemark("门店管理员");
        sysUser.setDelFlag(String.valueOf(0));
        sysUser.setStatus(String.valueOf(0));
        luntaiMapper.insertUser(sysUser);
        // 创建门店信息
        LuntaiStore luntaiStore = new LuntaiStore();
        luntaiStore.setCreateTime(new Date());
        luntaiStore.setAdminId(Math.toIntExact(sysUser.getUserId()));
        luntaiStore.setAdminPhone(luntaiUser.getPhone());
        luntaiStore.setName(applicationInfo.getStoreName());
        luntaiStore.setAddress(applicationInfo.getAddress());
        luntaiStore.setCity(applicationInfo.getCity());
        luntaiStore.setProvince(applicationInfo.getProvince());
        luntaiStore.setLatitude(applicationInfo.getLatitude());
        luntaiStore.setLongitude(applicationInfo.getLongitude());
        luntaiStore.setPhone(applicationInfo.getPhone());
        luntaiStore.setCover(applicationInfo.getCover());
        luntaiStore.setLicense(applicationInfo.getLicense());
        luntaiMapper.insertLuntaiStore(luntaiStore);
    }


    public void sendMessage(LuntaiStoreApplication luntaiStoreApplication) {
        LuntaiStoreApplication applicationInfo = luntaiMapper.selectLuntaiStoreApplicationById(luntaiStoreApplication.getId());
        String message = "消息内容";

        // 根据状态设置消息内容
        switch (luntaiStoreApplication.getStatus()) {
            case 1:
                message = "您申请的门店 " + applicationInfo.getStoreName() + " 已审批通过,管理员账号密码为您当前手机号";
                break;
            case 2:
                message = "您申请的门店 " + applicationInfo.getStoreName() + " 审批不通过,请核查后重新申请。" + "\n" + luntaiStoreApplication.getExt();
                break;
        }

        // 创建消息对象并保存
        Integer userId = applicationInfo.getUserId();
        LuntaiMessage luntaiMessage = new LuntaiMessage();
        luntaiMessage.setType(1);
        luntaiMessage.setTitle(message);
        luntaiMessage.setInfo(message);
        luntaiMessage.setUserId(userId);
        luntaiMessage.setIsread(0);
        luntaiMessage.setIsdelete(0);
        luntaiMapper.insertLuntaiMessage(luntaiMessage);
        LuntaiUser luntaiUser = luntaiMapper.selectLuntaiUserById(applicationInfo.getUserId());
        OfaPushVO ofaPushVO = new OfaPushVO();
        ofaPushVO.setOpenId(luntaiUser.getOpneid());
        ofaPushVO.setAuditType("门店申请");
        switch (luntaiStoreApplication.getStatus()) {
            case 1:
                ofaPushVO.setResult("已通过");
                ofaPushVO.setRemake("打开小程序查看站内信消息");
                break;
            case 2:
                ofaPushVO.setResult("已拒绝");
                ofaPushVO.setRemake("打开小程序查看拒绝理由");
                break;
        }
        sendAuditResult(ofaPushVO);
    }


    @Override
    public UserCarsDto getCarInfoById(Integer carId) {
        return luntaiMapper.getCarInfoById(carId);
    }


    @Override
    public HashMap<String, Object> getCarInfoByLicensePlate(String licensePlate) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("carInfo", null);
        map.put("tyreList", null);
        Integer carId = getCarInfoByLicensePlateVoid(licensePlate);
        if (carId < 1) {
            return map;
        }
        LuntaiUserCar carById = luntaiMapper.getCarById(carId);
        List<TyreInstallLogDto> tyreListByCarId2 = getTyreListByCarId2(carId);
        map.put("carInfo", carById);
        map.put("tyreList", tyreListByCarId2);
        return map;
    }


    private Integer getCarInfoByLicensePlateVoid(String licensePlate) {
        if (licensePlate == null || licensePlate.trim().isEmpty()) {
            return 0;
        }
        String cleanedInput = licensePlate.replaceAll("[\\p{Punct}\\s]", "").toUpperCase();
        if (cleanedInput.length() != 7 && cleanedInput.length() != 8) {
            return 0;
        }
        List<LuntaiUserCar> carList = luntaiMapper.getCarListByLicensePlate();
        List<LuntaiUserCar> filteredList = carList.stream()
                .filter(Objects::nonNull)
                .filter(car -> {
                    String plate = car.getLicensePlate();
                    if (plate == null) return false;
                    String cleaned = plate.replaceAll("[\\p{Punct}\\s]", "");
                    return cleaned.length() == 7 || cleaned.length() == 8;
                })
                .map(car -> {
                    String cleaned = car.getLicensePlate().replaceAll("[\\p{Punct}\\s]", "").toUpperCase();
                    car.setLicensePlate(cleaned);
                    return car;
                })
                .collect(Collectors.toList());

        // 查找 licensePlate 等于 cleanedInput 的那条记录并返回其 ID
        return filteredList.stream()
                .filter(car -> cleanedInput.equals(car.getLicensePlate()))
                .map(LuntaiUserCar::getId)
                .findFirst()
                .orElse(0);
    }


    @Override
    public void sendAuditResult(OfaPushVO ofaPushVO) {
        System.out.println("=========================");
        System.out.println("发送审核结果");
        System.out.println(ofaPushVO);
        System.out.println("=========================");
        String data =
                "{\n" +
                        "    \"touser\": \"" + ofaPushVO.getOpenId() + "\",\n" +
                        "    \"template_id\": \"R2mE4FSJM5Xoe0nD2-Ymp630VjYo09qsTbQ0beDRBNU\",\n" +
                        "    \"data\": {\n" +
                        "        \"phrase1\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getResult() + "\"\n" +
                        "        },\n" +
                        "        \"date2\": {\n" +  // 添加 date2 字段
                        "            \"value\": \"" + LachesismTools.getTime("yyyy年MM月dd日 HH:mm:ss") + "\"\n" +
                        "        },\n" +
                        "        \"phrase4\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getAuditType() + "\"\n" +
                        "        },\n" +
                        "        \"thing3\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getRemake() + "\"\n" +
                        "        }\n" +
                        "    }\n" +
                        "}";
        String token = getToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
        try {
            System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓    审核结果推送成功    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
            String s = LachesismTools.sendPost(url, null, data);
            System.out.println("请求结果为:  " + s);
            System.out.println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑    审核结果推送成功    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void sendAuditNotice(OfaPushVO ofaPushVO) {
        String data =
                "{\n" +
                        "    \"touser\": \"" + ofaPushVO.getOpenId() + "\",\n" +
                        "    \"template_id\": \"uUxjdW8Nad9MeTsGfCJVKe__GckU2x64m79mXARvdLE\",\n" +
                        "    \"data\": {\n" +
                        "        \"thing1\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getStoreName() + "\"\n" +
                        "        },\n" +
                        "        \"date2\": {\n" +  // 添加 date2 字段
                        "            \"value\": \"" + LachesismTools.getTime("yyyy-MM-dd HH:mm") + "\"\n" +
                        "        },\n" +
                        "        \"thing6\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getAuditInfo() + "\"\n" +
                        "        },\n" +
                        "        \"phone_number7\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getPhone() + "\"\n" +
                        "        }\n" +
                        "    }\n" +
                        "}";
        String token = getToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
        try {
            System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓    审核通知推送成功    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
            String s = LachesismTools.sendPost(url, null, data);
            System.out.println("请求结果为:  " + s);
            System.out.println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑    审核通知推送成功    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void sendAuditResult2(OfaPushVO ofaPushVO) {
        System.out.println("推送内容为：" + ofaPushVO);
        String data =
                "{\n" +
                        "    \"touser\": \"" + ofaPushVO.getOpenId() + "\",\n" +
                        "    \"template_id\": \"RpevymwxrZCbMYgiaIyTHc0YOWLbSCskL0NEidcLg48\",\n" +
                        "    \"data\": {\n" +
                        "        \"phrase1\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getResult() + "\"\n" +
                        "        },\n" +
                        "        \"thing3\": {\n" +  // 添加 date2 字段
                        "            \"value\": \"" + ofaPushVO.getRemake() + "\"\n" +
                        "        },\n" +
                        "        \"time12\": {\n" +
                        "            \"value\": \"" + LachesismTools.getTime("yyyy-MM-dd HH:mm") + "\"\n" +

                        "        },\n" +
                        "        \"phrase11\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getAuditType() + "\"\n" +
                        "        }\n" +
                        "    }\n" +
                        "}";
        String token = getToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
        try {
            System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓    审核通知推送成功    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
            String s = LachesismTools.sendPost(url, null, data);
            System.out.println("请求结果为:  " + s);
            System.out.println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑    审核通知推送成功    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void sendAuditResultToUser(OfaPushVO ofaPushVO) {
        System.out.println("推送内容为：" + ofaPushVO);
        String data =
                "{\n" +
                        "    \"touser\": \"" + ofaPushVO.getOpenId() + "\",\n" +
                        "    \"template_id\": \"RpevymwxrZCbMYgiaIyTHc0YOWLbSCskL0NEidcLg48\",\n" +
                        "    \"data\": {\n" +
                        "        \"phrase1\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getResult() + "\"\n" +
                        "        },\n" +
                        "        \"thing3\": {\n" +  // 添加 date2 字段
                        "            \"value\": \"" + ofaPushVO.getRemake() + "\"\n" +
                        "        },\n" +
                        "        \"time12\": {\n" +
                        "            \"value\": \"" + LachesismTools.getTime("yyyy-MM-dd HH:mm") + "\"\n" +

                        "        },\n" +
                        "        \"phrase11\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getAuditType() + "\"\n" +
                        "        }\n" +
                        "    }\n" +
                        "}";
        String token = getToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
        try {
            System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓    审核通知推送成功    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
            String s = LachesismTools.sendPost(url, null, data);
            System.out.println("请求结果为:  " + s);
            System.out.println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑    审核通知推送成功    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public void sendRequireAudit(OfaPushVO ofaPushVO) {
        String data =
                "{\n" +
                        "    \"touser\": \"" + ofaPushVO.getOpenId() + "\",\n" +
                        "    \"template_id\": \"uUxjdW8Nad9MeTsGfCJVKe__GckU2x64m79mXARvdLE\",\n" +
                        "    \"data\": {\n" +
                        "        \"thing1\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getStoreName() + "\"\n" +
                        "        },\n" +
                        "        \"phone_number7\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getPhone() + "\"\n" +
                        "        },\n" +
                        "        \"thing6\": {\n" +
                        "            \"value\": \"" + ofaPushVO.getAuditInfo() + "\"\n" +
                        "        },\n" +
                        "        \"date2\": {\n" +
                        "            \"value\": \"" + LachesismTools.getTime("yyyy年MM月dd日 HH:mm:ss") + "\"\n" +
                        "        }\n" +
                        "    }\n" +
                        "}";
        String token = getToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
        try {
            LachesismTools.sendPost(url, null, data);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Integer addTyreInfo(LuntaiUserTyre tyre) {
        Integer position = tyre.getPosition();
        List<LuntaiUserTyre> tyreInfoByCarId = luntaiMapper.getTyreInfoByCarId(tyre.getCarId(), position);
        if (tyreInfoByCarId != null && !tyreInfoByCarId.isEmpty()) {
            tyre.setId(tyreInfoByCarId.get(0).getId());
            luntaiMapper.updateTyreInfo(tyre);
            return tyreInfoByCarId.get(0).getId();
        } else {
            tyre.setUserId(MemberUtil.getUserId());
            luntaiMapper.addTyreInfo(tyre);
            return tyre.getId();
        }
    }

    public void createOrder(Integer type, Integer sourceId, Integer storeId, Integer userId) {
        System.out.println(type + "  " + sourceId + "  " + storeId + "   " + userId);
        LuntaiOrder luntaiOrder = new LuntaiOrder();
        luntaiOrder.setUserId(userId);
        luntaiOrder.setSourceId(sourceId);
        luntaiOrder.setType(type);
        luntaiOrder.setStoreId(storeId);
        luntaiOrder.setOrderSn(type.toString() + storeId.toString() + sourceId.toString() + userId + LachesismTools.generateOrderSn());
        luntaiMapper.createOrder(luntaiOrder);
    }

    public LuntaiTyre getTyreByCarId(Integer carId) {
        return luntaiMapper.getTyreByCarId(carId);
    }

    public LuntaiOrder getOrderByRequest(Integer type, Integer sourceId) {
        return luntaiMapper.getPolicyExtensionOrderInfo(type, sourceId);
    }

    public LuntaiStore getStoreByStoreId(Integer storeId) {
        return luntaiMapper.getStoreByStoreId(storeId);
    }

    public LuntaiUserCar getCarById(Integer carId) {
        return luntaiMapper.getCarById(carId);
    }

    public List<LuntaiUserTyre> getRequestTyreListByRequestId(Integer requestId) {
        return luntaiMapper.getRequestTyreListByRequestId(requestId);
    }

    public String getToken() {
        String token = (String) redisService.getWithTimeout("token");
        if (token == null || token.equals("")) {
            String accessToken = getStableAccessToken();
            setAccessToken(accessToken);
            return accessToken;
        }
        return token;
    }

    private String getAccessToken() {
        String urlString = "https://api.weixin.qq.com/cgi-bin/token";
        JSONObject json = new JSONObject();
        json.put("grant_type", "client_credential");
        json.put("appid", appID);
        json.put("secret", appSecret);
        String result = CommonUtil.httpsRequest(urlString, "POST", json.toString());
        Map<String, String> parse = JSON.parseObject(result, new TypeReference<Map<String, String>>() {
        });
        return parse.get("access_token");
    }

    private String getStableAccessToken() {
        String urlString = "https://api.weixin.qq.com/cgi-bin/stable_token";
        JSONObject json = new JSONObject();
        json.put("grant_type", "client_credential");
        json.put("appid", appID);
        json.put("secret", appSecret);
        String result = CommonUtil.httpsRequest(urlString, "POST", json.toString());
        Map<String, String> parse = JSON.parseObject(result, new TypeReference<Map<String, String>>() {
        });
        String token = parse.get("access_token");
        return token;
    }

    private void setAccessToken(String token) {
        redisService.set("token", token, 2, TimeUnit.HOURS);
    }

    private Boolean getAuditStatus(Integer type) {
        Integer result = luntaiMapper.getAuditStatus(type);
        return result.equals(1);
    }

    @Override
    public ClaimDetailInfoDto getDetailInfoByClaimId(Integer requestId) {
        ClaimDetailInfoDto detailInfoDto = new ClaimDetailInfoDto();
        LuntaiClaimsRequest claimRequest = luntaiMapper.getClaimRequest(requestId);
        //获取申请详情
        detailInfoDto.setRequest(claimRequest);
        LuntaiTyreInstallLog tyre = luntaiMapper.getTyreById(claimRequest.getTyreId());
        detailInfoDto.setBeforeTyreInfo(tyre);
        //获取轮胎安装之前记录
        detailInfoDto.setAfterTyreInfo(luntaiMapper.getAfterTyreInfo(claimRequest.getCode()));
        //获取轮胎之后记录
        detailInfoDto.setQrcode("data:image/png;base64," + generateQRCodeBase64(String.valueOf(requestId)));
        LuntaiTyreInstallRequest tyreInstallRequestInfo = luntaiMapper.getTyreInstallRequestInfo(tyre.getRequestId());
        detailInfoDto.setCarInfo(luntaiMapper.getCarById(tyreInstallRequestInfo.getCarId()));
        LuntaiTyreInstallRequest request = luntaiMapper.getInstallTyreRequestByTyreId(tyre.getId());
        detailInfoDto.setStoreInfo(luntaiMapper.getStoreByStoreId(request.getStoreId()));
        detailInfoDto.setOrderSn(luntaiMapper.getOrderSn(requestId, 4));
        return detailInfoDto;
    }

    private void addAuditLog(Integer result, SysUser admin, Integer sourceId, Integer type) {
        AuditLog auditLog = new AuditLog();
        auditLog.setSourceId(sourceId);
        auditLog.setSourceType(type);
        auditLog.setAdminId(admin.getUserId());
        auditLog.setAdminPhone(admin.getPhonenumber());
        auditLog.setResult(result);
        luntaiMapper.addAuditLog(auditLog);
    }
}
